<template>
	<view class="content">
		<view id="viewport" @click="ray" />
		<control ref="control" :hotPoint="curSelectHotPoint" @exportJSON="exportJSON" @deleteItem="deleteItem" />
	</view>
</template>

<script>
	import config from './config.js';

	import * as THREE from 'three';
	let OrbitControls = require('three-orbit-controls')(THREE);
	THREE.OrbitControls = OrbitControls;

	import control from './components/control.vue';
	let INDEX = 0;

	export default {
		components: {
			control
		},
		data() {
			return {
				scene: null,
				camera: null,
				renderer: null,
				controls: null,
				canvas: null,
				elements: [],
				curSelectHotPoint: null,
				pageConfig: JSON.parse(JSON.stringify(config))
			}
		},
		mounted() {
			uni.showToast({
				title: '点击即可添加热点',
				icon: 'none',
				duration: 3000
			})
			this.initThree();
		},
		methods: {
			async initThree() {
				let scene, camera, renderer, controls;

				let viewport = document.getElementById('viewport');

				let {
					offsetWidth: width,
					offsetHeight: height
				} = viewport;

				//场景
				scene = new THREE.Scene();
				//镜头
				camera = new THREE.PerspectiveCamera(90, width / height, 0.1, 100);
				camera.position.set(0, 0, 0.01);
				//渲染器
				renderer = new THREE.WebGLRenderer();
				renderer.setSize(width, height);
				viewport.appendChild(renderer.domElement);
				//镜头控制器
				controls = new THREE.OrbitControls(camera, renderer.domElement);

				this.camera = camera;
				this.scene = scene;
				this.renderer = renderer;
				this.controls = controls;
				this.canvas = renderer.domElement;

				this.initSkyBox();
				this.updateView();

				if (this.pageConfig.hotPoints.length > 0) {
					this.pageConfig.hotPoints.forEach(item => {
						let pos = new THREE.Vector3(item.position.x, item.position.y, item.position.z);
						let scale = new THREE.Vector3(item.scale.x, item.scale.y, item.scale.z);
						this.addSprite(item.imageSrc, pos, scale);
					})
				}

			},
			initSkyBox() {

				let {
					skyboxPath,
					skyboxImages
				} = this.pageConfig;

				this.$utils.cubeTextureLoader(skyboxPath, skyboxImages).then(res => {
					this.scene.background = res;
				})
			},
			ray(e) {
				let {
					canvas,
					camera,
					scene
				} = this.$data;

				let {
					clientX,
					clientY
				} = e.changedTouches[0];

				// 坐标归一化
				clientY += (canvas.getBoundingClientRect().top / 2);
				let x = (clientX / window.innerWidth) * 2 - 1;
				let y = -(clientY / window.innerHeight) * 2 + 1

				let vector3 = new THREE.Vector3(x, y, 1);
				let worldVector = vector3.unproject(camera);
				let ray = worldVector.sub(camera.position).normalize();

				// 判断当前是否选中物体
				let element = this.$utils.getIntersects(x, y, this.elements, this.camera, this.scene);

				if (element) {
					this.curSelectHotPoint = element;
				} else {
					let hotImageUrl = this.$refs.control.hotImageUrl;
					this.curSelectHotPoint = this.addSprite(hotImageUrl, this.$utils.getPosByDirection(camera
						.position, ray, 10));
				}
			},
			// 创建一个图片元素
			addSprite(src, pos, scale = new THREE.Vector3(1, 1, 1)) {
				let sprite = this.$utils.createSprite(src, pos, scale);
				sprite.name = 'hotpoint_' + INDEX++;
				this.scene.add(sprite);
				this.elements.push(sprite);
				return sprite;
			},
			updateView() {
				let {
					renderer,
					scene,
					camera
				} = this.$data;

				requestAnimationFrame(this.updateView);
				renderer.render(scene, camera);
			},
			// 导出当前配置
			exportJSON() {
				

				let json = JSON.stringify({
					skyboxPath: this.pageConfig.skyboxPath,
					skyboxImages: this.pageConfig.skyboxImages,
					hotPoints: this.elements.map(item => {
						let position = {
							x: item.position.x,
							y: item.position.y,
							z: item.position.z
						}
						let scale = {
							x: item.scale.x,
							y: item.scale.y,
							z: item.scale.z
						}
						let imageSrc = item.material.map.image.currentSrc;
						
						let imageURL = new URL(imageSrc);
						if(imageURL.origin.includes('localhost')){
							imageSrc = imageURL.pathname;
						}
						
						return {
							position,
							scale,
							imageSrc
						}
					})
				});

				console.log('==========直接复制以下json到index/config.js访问pages/index即可看到与当前编辑相同效果==============');
				console.log('module.exports = ' + json);
				console.log('========================');
				
				uni.showToast({
					title: '当前配置导出成功，请在控制台查看JSON',
					duration: '5000'
				});
				
			},
			// 获取相对路径
			getUrlRelativePath(url) {
				var arrUrl = url.split("//");
				var start = arrUrl[1].indexOf("/");
				var relUrl = arrUrl[1].substring(start); //stop省略，截取从start开始到结尾的所有字符
				if (relUrl.indexOf("?") != -1) {
					relUrl = relUrl.split("?")[0];
				}
				return relUrl;
			},
			// 删除元素
			deleteItem(sprice) {
				this.scene.remove(sprice);
				this.elements.splice(this.elements.findIndex(item => item.name == sprice.name), 1);
				this.curSelectHotPoint = null;
			}
		}
	}
</script>

<style>
	#viewport {
		position: absolute;
		left: 0;
		top: 0;
		width: 100%;
		height: 100%;
	}
</style>
